package br.com.sgpv2.service.pessoa;

import java.util.List;

import org.hibernate.HibernateException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import br.com.sgpv2.controler.NegocioExeception;
import br.com.sgpv2.entity.cargos.CargoFuncao;
import br.com.sgpv2.entity.organograma.Departamento;
import br.com.sgpv2.entity.organograma.Nivel;
import br.com.sgpv2.entity.organograma.Secretaria;
import br.com.sgpv2.entity.pessoa.Pessoa;
import br.com.sgpv2.entity.pessoa.PessoaDTO;
import br.com.sgpv2.entity.pessoa.endereco.Cidade;
import br.com.sgpv2.entity.pessoa.endereco.Estado;
import br.com.sgpv2.entity.pessoa.endereco.Pais;
import br.com.sgpv2.hibernate.pessoa.PessoaRepository;

/**
 * Classe de serviço de Pessoa.
 */
@Service(value = "pessoaService")
@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
public class PessoaServiceImpl implements PessoaService {

	private PessoaRepository pessoaRepository;

	/**
	 * Configura o DAO de pessoa.
	 */
	@Autowired
	public void setPessoaRepository(PessoaRepository pessoaRepository) {
		this.pessoaRepository = pessoaRepository;
	}

	/**
	 * Salva a entidade pessoa.
	 * 
	 * @param pessoa
	 *            a pessoa a ser salva.
	 */
	@Override
	public Pessoa salvar(Pessoa pessoa) throws Exception {
		try {
			this.pessoaRepository.salvar(pessoa);
			return pessoa;
		} catch (HibernateException e) {
			throw new Exception("N�o foi poss�vel salvar. " + e.getMessage());
		}
	}

	/**
	 * Busca a entidade pessoa pelo id.
	 * 
	 * @param pk
	 *            id da pessoa.
	 */
	public Pessoa buscar(Integer pk) throws NegocioExeception {
		Pessoa pessoa = pessoaRepository.buscar(pk);
		if (pessoa == null) {
			throw new NegocioExeception(
					"Pessoa não cadastrada no banco de dados.");
		}
		return pessoa;
	}

	/**
	 * Altera a entidade pessoa.
	 * 
	 * @param pessoa
	 *            a pessoa a ser alterada.
	 */
	public void alterar(Pessoa pessoa) {
		this.pessoaRepository.alterar(pessoa);
	}

	/**
	 * Remove a entidade pessoa do banco de dados.
	 * 
	 * @param pessoa
	 *            a pessoa a ser removida.
	 */
	@Transactional(isolation = Isolation.DEFAULT, rollbackFor = Exception.class)
	public void remover(Pessoa pessoa) throws Exception {
		try {
			this.pessoaRepository.excluir(pessoa);
		} catch (HibernateException e) {
			throw new Exception("Não foi possível remover. " + e.getMessage());
		}
	}

	/**
	 * Lista todas as entidades de pessoas no banco de dados.
	 * 
	 */
	public List<Pessoa> listar() throws Exception {
		try {
			return this.pessoaRepository.listar();
		} catch (HibernateException e) {
			throw new Exception("Não foi possível listar. " + e.getMessage());
		}
	}

	/**
	 * Consulta todas as cidades por estado.
	 * 
	 * @param siglaEstado
	 *            o estado a ser usado como filtro.
	 */
	public List<Cidade> consultarCidadesPorEstado(String siglaEstado) {
		return this.pessoaRepository.consultarCidadesPorEstado(siglaEstado);
	}

	/**
	 * Consulta todos os estados por país.
	 * 
	 * @param pais
	 *            o país usado como filtro.
	 */
	public List<Estado> consultarEstadosPorPais(Pais pais) {
		return this.pessoaRepository.consultarEstadosPorPais(pais);
	}

	/**
	 * Consulta todos países no banco de dados.
	 * 
	 */
	public List<Pais> consultarPaises() {
		return this.pessoaRepository.consultarPaises();
	}

	/**
	 * Lista as pessoas do banco de dados transformando o resultado no DTO para
	 * mostrar na tela.
	 * 
	 */
	public List<PessoaDTO> consultarPessoaDTO() {
		return this.pessoaRepository.consultarPessoaDTO();
	}

	/**
	 * Lista as pessoas do banco de dados transformando o resultado no DTO para
	 * mostrar na tela mediante aos filtros informados.
	 * 
	 */
	public List<PessoaDTO> consultarPessoasDTOPorFiltro(String nome,
			String cpf, String identidade) {
		return pessoaRepository.consultarPessoasDTOPorFiltro(nome, cpf,
				identidade);
	}

	@Override
	public Pais buscarPaisPorNome(String paisTransiente) {
		return pessoaRepository.buscarPaisPorNome(paisTransiente);
	}

	@Override
	public Estado buscarEstadoPorNome(String estadoTransiente) {
		return pessoaRepository.buscarEstadoPorNome(estadoTransiente);
	}

	@Override
	public Cidade buscarCidadePorNome(String cidadeTransiente) {
		return pessoaRepository.buscarCidadePorNome(cidadeTransiente);
	}

	@Override
	public List<Nivel> getNiveis() {
		return pessoaRepository.getNiveis();
	}

	@Override
	public List<CargoFuncao> getCargosFuncoes() {
		return pessoaRepository.getCargosFuncoes();
	}

	@Override
	public List<Departamento> getDepartamentos() {
		return pessoaRepository.getDepartamentos();
	}

	@Override
	public List<Secretaria> getSecretarias() {
		return pessoaRepository.getSecretarias();
	}

	@Override
	public Secretaria buscarSecretariaPorDescricao(String descricao) {
		return pessoaRepository.buscarSecretariaPorDescricao(descricao);
	}

	@Override
	public Departamento buscarDepartamentoPorDescricao(String descricao) {
		return pessoaRepository.buscarDepartamentoPorDescricao(descricao);
	}

	@Override
	public CargoFuncao buscarCargoFuncaoPorDescricao(String descricao) {
		return pessoaRepository.buscarCargoFuncaoPorDescricao(descricao);
	}

	@Override
	public Nivel buscarNivelPorDescricao(String codigo) {
		return pessoaRepository.buscarNivelPorDescricao(codigo);
	}
}
